package Principal;

import java.io.IOException;
import javax.microedition.rms.*;

/**
 *  Registro de monedas. Se encarga de realizar todas las operaciones relacionadas con el registro
 * donde se guardan los datos de las monedas.
 * @author Noelia Alonso Garrido
 * @author Abel Torres Alonso
 * @author Diego Vallejo Alonso
 */
public class RegistroMonedas {

    private static RecordStore rMonedas;

    public RegistroMonedas() {
        rMonedas = null;
    }

    /**
     * Abre el registro de monedas. Crea uno nuevo si no existe ninguno previo.
     */
    public void abrirRegistroMonedas() {

        try {
            rMonedas = RecordStore.openRecordStore("Monedas", true);
            System.out.println("Número de registros: " + rMonedas.getNumRecords());

            /* Si el registro tiene menos de seis monedas, es porque es nuevo y hay que rellenarlo
             * con las monedas obligatorias.
             */
            if (rMonedas.getNumRecords() < 6) {
                Moneda m = new Moneda("Euros", "EUR", (float) 1);
                insertaMoneda(m);

                m = new Moneda("US Dollar", "USD", (float) 0.7087);
                try {
                    m.actualizaEquivalencia();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                insertaMoneda(m);

                m = new Moneda("British Pound Sterling", "GBP", (float) 1.1479);
                  try {
                    m.actualizaEquivalencia();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                insertaMoneda(m);

                m = new Moneda("Swiss Franc", "CHF", (float) 0.7939);
                  try {
                    m.actualizaEquivalencia();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                insertaMoneda(m);

                m = new Moneda("Japanese Yen", "JPY", (float) 0.0088);
                  try {
                    m.actualizaEquivalencia();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                insertaMoneda(m);

                m = new Moneda("Australian Dollar", "AUD", (float) 0.7495);  try {
                    m.actualizaEquivalencia();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

                insertaMoneda(m);

                System.out.println("Número de registros: " + rMonedas.getNumRecords());
            }
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Inserta una moneda en el registro
     * @param mon La moneda a insertar en el registro.
     */
    public void insertaMoneda(Moneda mon) {
        byte[] registro;
        try {
            registro = mon.aByteArray();
            rMonedas.addRecord(registro, 0, registro.length);

        } catch (IOException ex) {
            System.out.println("Fallo al serializar un objeto moneda");
        } catch (RecordStoreNotOpenException er) {
            System.out.println("Fallo porque el registro no está abierto");
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Reemplaza la moneda en que haya en la posición indicada por una nueva
     * @param mon   La nueva moneda
     * @param posicion  La posición en la que está la moneda a reemplazar
     */

     public void reemplazaMoneda(Moneda mon, int posicion) {
        byte[] registro;
        try {
            registro = mon.aByteArray();
            rMonedas.setRecord(posicion, registro, 0, registro.length);

        } catch (IOException ex) {
            System.out.println("Fallo al serializar un objeto moneda");
        } catch (RecordStoreNotOpenException er) {
            System.out.println("Fallo porque el registro no está abierto");
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Extrae del registro la moneda que ocupa la posición indicada.
     * @param posicion del registro que queremos obtener. Debe estar validada (obtenida de una enumeración)
     * @return La moneda que está en esa posición.
     * @throws RecordStoreNotOpenException
     * @throws InvalidRecordIDException
     * @throws RecordStoreException
     */
    public Moneda extraeMoneda(int posicion) throws RecordStoreNotOpenException, InvalidRecordIDException, RecordStoreException {
        Moneda m = new Moneda();
            int tamano = rMonedas.getRecordSize(posicion);
            byte[] registro = new byte[tamano];
            rMonedas.getRecord(posicion, registro, 0);
            try {
                m.desdeByteArray(registro);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return m;
    }

    /**
     * Cierra el registro de manera segura.
     */
    public void cierraRegistro() {
        try {
            rMonedas.closeRecordStore();
        } catch (RecordStoreNotOpenException ex) {
            ex.printStackTrace();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Informa del número de monedas que hay en el registro.
     * @return el número de monedas diferentes almacendas en el registro.
     * @throws RecordStoreNotOpenException
     */
    public int contarMonedas() throws RecordStoreNotOpenException {
        return rMonedas.getNumRecords();
    }


    /**
     * Borra la moneda que está en una posición determinada del registro
     * @param posicion  La posición del registro que se quiere borrar.
     * @return
     */

    public boolean borrarMoneda(int posicion) {
        RecordEnumeration r;

        try {
            rMonedas.deleteRecord(posicion);
            System.out.println("Monedas guardadas:" + rMonedas.getNumRecords());
            return true;
        } catch (RecordStoreNotOpenException ex) {
            ex.printStackTrace();
        } catch (InvalidRecordIDException ex) {
            ex.printStackTrace();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
        return true;
    }

    /**
     * Devuelve una enumeración para navegar por el registro
     * @return enumeración para navegar por el registro
     */

    public RecordEnumeration getEnumeracion(){
        try {
            RecordEnumeration re = rMonedas.enumerateRecords(null, null, false);
            return re;
        } catch (RecordStoreNotOpenException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * Busca en el registro la moneda con el código de moneda indicado
     * @param codigo el código de la moneda a encontrar
     * @return la moneda con ese código si está en el registro, o null.
     */

    public Moneda buscarMoneda(String codigo){
        try {
            Moneda m = new Moneda(null, codigo, (float) 0); //Creamos una moneda con ese código y se la pasamos al filtro
            FiltroMonedas fM = new FiltroMonedas(m);
            int id;
            RecordEnumeration re = rMonedas.enumerateRecords(fM, null, false); //Solicitamos al registro una enumeración de monedas
            if (re.numRecords() > 0) {                                          //que pasen el filtro
                id = re.previousRecordId();
                return extraeMoneda(id);
            }
            return null;
        } catch (RecordStoreNotOpenException ex) {
            ex.printStackTrace();
        } catch (InvalidRecordIDException ex) {
            ex.printStackTrace();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
        return null;
    }
}